/*
 * Copyright 2009 SHOP.COM
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.shop.opensocial.mediated.services;

import com.shop.opensocial.mediated.request.MediatedRequest;
import com.shop.opensocial.mediated.types.OAuthConsumerMediator;
import com.shop.opensocial.mediated.types.OAuthServiceProviderMediator;
import com.shop.opensocial.mediated.types.SecurityTokenMediator;

/**
 * Independent mediator for corresponding OpenSocial type
 *
 * @author Jordan Zimmerman
 */
public interface OAuthStoreMediator
{
	/**
	 * Information about an OAuth consumer.
	 */
	public static class ConsumerInfo
	{
		private final OAuthConsumerMediator consumer;
		private final String keyName;

		/**
		 * @param consumer the OAuth consumer
		 * @param keyName  the name of the key to use for this consumer (passed on query parameters to
		 *                 help with key rotation.)
		 */
		public ConsumerInfo(OAuthConsumerMediator consumer, String keyName)
		{
			this.consumer = consumer;
			this.keyName = keyName;
		}

		public OAuthConsumerMediator getConsumer()
		{
			return consumer;
		}

		public String getKeyName()
		{
			return keyName;
		}
	}

	/**
	 * Information about an access token.
	 */
	public static class TokenInfo
	{
		private final String accessToken;
		private final String tokenSecret;
		private final String sessionHandle;
		private final long tokenExpireMillis;

		/**
		 * @param accessToken	   the token
		 * @param tokenSecret	   the secret for the token
		 * @param sessionHandle	 the session handle
		 *                          (http://oauth.googlecode.com/svn/spec/ext/session/1.0/drafts/1/spec.html)
		 * @param tokenExpireMillis time (milliseconds since epoch) when the token expires
		 */
		public TokenInfo(String accessToken, String tokenSecret, String sessionHandle, long tokenExpireMillis)
		{
			this.accessToken = accessToken;
			this.tokenSecret = tokenSecret;
			this.sessionHandle = sessionHandle;
			this.tokenExpireMillis = tokenExpireMillis;
		}

		public String getAccessToken()
		{
			return accessToken;
		}

		public String getTokenSecret()
		{
			return tokenSecret;
		}

		public String getSessionHandle()
		{
			return sessionHandle;
		}

		public long getTokenExpireMillis()
		{
			return tokenExpireMillis;
		}
	}

	/**
	 * Retrieve OAuth consumer to use for requests.  The returned consumer is ready to use for signed
	 * fetch requests.
	 *
	 * @param request The request
	 * @param securityToken token for user/gadget making request.
	 * @param serviceName   gadget's nickname for the service being accessed.
	 * @param provider	  OAuth service provider info to be inserted into the returned consumer. @throws Exception if no OAuth consumer can be found (e.g. no consumer key can be used.)
	 * @return consumer info
	 * @throws Exception errors
	 */
	public ConsumerInfo getConsumerKeyAndSecret(MediatedRequest request, SecurityTokenMediator securityToken, String serviceName, OAuthServiceProviderMediator provider) throws Exception;

	/**
	 * Retrieve OAuth access token to use for the request.
	 *
	 * @param request The request
	 * @param securityToken token for user/gadget making request.
	 * @param consumerInfo  OAuth consumer that will be used for the request.
	 * @param serviceName   gadget's nickname for the service being accessed.
	 * @param tokenName	 gadget's nickname for the token to use. @return the token and secret, or null if none exist
	 * @return token info
	 * @throws Exception if an error occurs during lookup
	 */
	public TokenInfo getTokenInfo(MediatedRequest request, SecurityTokenMediator securityToken, ConsumerInfo consumerInfo, String serviceName, String tokenName) throws Exception;

	/**
	 * Set the access token for the given user/gadget/service/token
	 *
	 * @param request The request
	 * @param securityToken token for user/gadget making request.
	 * @param consumerInfo  OAuth consumer that will be used for the request.
	 * @param serviceName   gadget's nickname for the service being accessed.
	 * @param tokenName	 gadget's nickname for the token to use.
	 * @param tokenInfo the token info
	 * @throws Exception if an error occurs during lookup
	 */
	public void setTokenInfo(MediatedRequest request, SecurityTokenMediator securityToken, ConsumerInfo consumerInfo, String serviceName, String tokenName, TokenInfo tokenInfo) throws Exception;

	/**
	 * Remove the access token for the given user/gadget/service/token
	 *
	 * @param request The request
	 * @param securityToken token for user/gadget making request.
	 * @param consumerInfo  OAuth consumer that will be used for the request.
	 * @param serviceName   gadget's nickname for the service being accessed.
	 * @param tokenName	 gadget's nickname for the token to use.
	 * @throws Exception if an error occurs during lookup
	 */
	public void removeToken(MediatedRequest request, SecurityTokenMediator securityToken, ConsumerInfo consumerInfo, String serviceName, String tokenName) throws Exception;
}

